﻿// Copyright (c) 2010
// by OpenLight Group
// http://openlightgroup.net/
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
//
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.


using System;
using System.Linq;
using System.IO;
using System.Web;
using System.Collections.Generic;
using System.Drawing;

namespace SimpleMVVMFileUpload
{
    public delegate void FileUploadCompletedEvent(object sender, FileUploadCompletedEventArgs args);
    
    #region FileUploadCompletedEventArgs
    public class FileUploadCompletedEventArgs
    {
        public string FileName { get; set; }
        public string FilePath { get; set; }

        public FileUploadCompletedEventArgs() { }

        public FileUploadCompletedEventArgs(string fileName, string filePath)
        {
            FileName = fileName;
            FilePath = filePath;
        }
    }
    #endregion

    #region class FileUploadProcess
    public class FileUploadProcess
    {
        public event FileUploadCompletedEvent FileUploadCompleted;
        public int imgWidth { get; set; }
        public int imgHeight { get; set; }
        public string imageType { get; set; }
        #region ProcessRequest
        public void ProcessRequest(HttpContext context)
        {
            // Values passed
            string fileNameforSEO = string.IsNullOrEmpty(context.Request.QueryString["fileNameforSEO"]) ? "Unknown" : context.Request.QueryString["fileNameforSEO"];
            string Originalfilename = string.IsNullOrEmpty(context.Request.QueryString["filename"]) ? "Unknown" : context.Request.QueryString["filename"];
            bool complete = string.IsNullOrEmpty(context.Request.QueryString["Complete"]) ? true : bool.Parse(context.Request.QueryString["Complete"]);
            bool getBytes = string.IsNullOrEmpty(context.Request.QueryString["GetBytes"]) ? false : bool.Parse(context.Request.QueryString["GetBytes"]);
            long startByte = string.IsNullOrEmpty(context.Request.QueryString["StartByte"]) ? 0 : long.Parse(context.Request.QueryString["StartByte"]); ;
            string saveLocation = string.IsNullOrEmpty(context.Request.QueryString["saveLocation"]) ? "Unknown" : context.Request.QueryString["saveLocation"];
            int imgWidth = string.IsNullOrEmpty(context.Request.QueryString["imgWidth"]) ? 0 : int.Parse(context.Request.QueryString["imgWidth"]);
            int imgHeight = string.IsNullOrEmpty(context.Request.QueryString["imgHeight"]) ? 0 : int.Parse(context.Request.QueryString["imgHeight"]);
            string imageType = string.IsNullOrEmpty(context.Request.QueryString["imageType"]) ? "Unknown" : context.Request.QueryString["imageType"];
            

            string strExtension = System.IO.Path.GetExtension(Originalfilename);
            string strFileDirectory = context.ApplicationInstance.Server.MapPath(@"~\");

            // Find instance of "bin"
            int intPositionOfBin = strFileDirectory.ToLower().IndexOf("bin");
            if (intPositionOfBin > -1)
            {
                strFileDirectory = strFileDirectory.Substring(0, intPositionOfBin);
            }

            strFileDirectory = strFileDirectory + @"Files\" + saveLocation + @"\" + imageType;
            EnsureDirectory(new System.IO.DirectoryInfo(strFileDirectory));


            //rebuild file name for SEO ----------- Originalfilename = passed from LocationsListDetail
            string filePath = Path.Combine(strFileDirectory, fileNameforSEO);
            //string filePath = Path.Combine(strFileDirectory, Originalfilename);

            // Check File Extension
            // This will throw a fatal exception, but the Client should 
            // catch the invalid extension before it gets this far
            if (!CheckFileExtension(strExtension))
            {
                context.Response.Write("0");
                context.Response.Flush();
                return;
            }

            if (getBytes)
            {
                FileInfo fi = new FileInfo(filePath);

                // If file exists - delete it
                if (fi.Exists)
                {
                    try
                    {
                        fi.Delete();
                    }
                    catch
                    {
                        // could not delete
                    }
                }

                context.Response.Write("0");
                context.Response.Flush();
                return;
            }
            else
            {
                if (startByte > 0 && File.Exists(filePath))
                {
                    using (FileStream fs = File.Open(filePath, FileMode.Append))
                    {
                        SaveFile(context.Request.InputStream, fs, imgWidth, imgHeight );
                        fs.Close();
                    }
                }
                else
                {
                    using (FileStream fs = File.Create(filePath))
                    {
                        SaveFile(context.Request.InputStream, fs, imgWidth, imgHeight);
                        fs.Close();
                    }
                }
                if (complete)
                {
                    if (FileUploadCompleted != null)
                    {
                        FileUploadCompletedEventArgs args = new FileUploadCompletedEventArgs(Originalfilename, filePath);
                        FileUploadCompleted(this, args);
                    }
                }
            }
        }
        #endregion

        #region SaveFile
        private void SaveFile(Stream stream, FileStream fs, int iWidth, int iHeight)
        {
            //byte[] buffer = new byte[4096];
            //int bytesRead;
            //while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) != 0)
            //{
            //    fs.Write(buffer, 0, bytesRead );
            //}

            String loc = fs.Name;
            fs.Dispose();
            Bitmap bmp = new Bitmap(stream);
            Bitmap newBMP = new Bitmap(bmp, iWidth, iHeight);
            
            Graphics oGraphics = Graphics.FromImage(newBMP);


            oGraphics.DrawImage(bmp, 0, 0, imgWidth, imgHeight);

            newBMP.Save(loc);


            //' Once finished with the bitmap objects, we deallocate them.
            bmp.Dispose();
            newBMP.Dispose();
            oGraphics.Dispose();
        }
        #endregion

        #region CheckFileExtension
        private bool CheckFileExtension(string strExtension)
        {
            if (
             string.Compare(Path.GetExtension(strExtension).ToLower(), ".gif", true) != 0
             & string.Compare(Path.GetExtension(strExtension).ToLower(), ".jpg", true) != 0
             & string.Compare(Path.GetExtension(strExtension).ToLower(), ".jpeg", true) != 0
             & string.Compare(Path.GetExtension(strExtension).ToLower(), ".doc", true) != 0
             & string.Compare(Path.GetExtension(strExtension).ToLower(), ".docx", true) != 0
             & string.Compare(Path.GetExtension(strExtension).ToLower(), ".xls", true) != 0
             & string.Compare(Path.GetExtension(strExtension).ToLower(), ".xlsx", true) != 0
             & string.Compare(Path.GetExtension(strExtension).ToLower(), ".pdf", true) != 0
             & string.Compare(Path.GetExtension(strExtension).ToLower(), ".txt", true) != 0
             & string.Compare(Path.GetExtension(strExtension).ToLower(), ".png", true) != 0
             )
            {
                return false;
            }
            else
            {
                return true;
            }
        } 
        #endregion

        #region EnsureDirectory
        public static void EnsureDirectory(System.IO.DirectoryInfo oDirInfo)
        {
            if (oDirInfo.Parent != null)
                EnsureDirectory(oDirInfo.Parent);
            if (!oDirInfo.Exists)
            {
                oDirInfo.Create();
            }
        } 
        #endregion
    }
    #endregion
}